package cn.miju.admin.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.miju.admin.framework.model.BaseInfo;
import cn.miju.admin.system.service.RoleService;
import cn.miju.admin.system.vo.*;
import cn.miju.database.entity.SysMenuAuthRole;
import cn.miju.database.entity.SysRole;
import cn.miju.database.mapper.SysMenuAuthRoleMapper;
import cn.miju.database.mapper.SysRoleMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <pre>
 * 角色管理
 * </pre>
 *
 * @author zhuming
 * @version 1.0.0
 * @since 2023-04-03 14:46
 */
@Service
@RequiredArgsConstructor
public class RoleServiceImpl implements RoleService {
    private final SysRoleMapper sysRoleMapper;
    private final SysMenuAuthRoleMapper sysMenuAuthRoleMapper;

    /**
     * 角色分页查询
     * @param inVO {@link RolePageInVO}
     * @return {@link Page<RolePageOutVO>}
     */
    @Override
    public Page<RolePageOutVO> getPage(RolePageInVO inVO) {
        LambdaQueryWrapper<SysRole> queryWrapper = Wrappers.lambdaQuery();
        if (StringUtils.isNotBlank(inVO.getKeyword())) {
            queryWrapper.like(SysRole::getRoleName, inVO.getKeyword());
            queryWrapper.or(childQueryWrapper -> childQueryWrapper.like(SysRole::getRoleCode, inVO.getKeyword()));
        }
        Page<SysRole> sysRolePage = sysRoleMapper.selectPage(new Page<>(inVO.getPage(), inVO.getPageSize()), queryWrapper);
        Page<RolePageOutVO> page = new Page<>();
        BeanUtil.copyProperties(sysRolePage, page);
        page.setRecords(sysRolePage.getRecords().stream().map(sysRole -> {
            RolePageOutVO outVO = new RolePageOutVO();
            outVO.setId(sysRole.getId());
            outVO.setRoleCode(sysRole.getRoleCode());
            outVO.setRoleName(sysRole.getRoleName());
            outVO.setCreatedTime(sysRole.getCreatedTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            outVO.setRemark(sysRole.getRemark());
            return outVO;
        }).collect(Collectors.toList()));
        return page;
    }

    /**
     * 保存角色信息
     * @param inVO {@link RoleSaveInVO}
     */
    @Override
    public void save(RoleSaveInVO inVO) {
        if (null == inVO.getId() || 0 == inVO.getId()) {
            sysRoleMapper.insert(SysRole.builder().roleName(inVO.getRoleName()).roleCode(inVO.getRoleCode()).remark(inVO.getRemark()).build());
        } else {
            sysRoleMapper.update(null, Wrappers.<SysRole>lambdaUpdate().
                    set(SysRole::getRoleName, inVO.getRoleName()).
                    set(SysRole::getRoleCode, inVO.getRoleCode()).
                    set(SysRole::getRemark, inVO.getRemark()).
                    set(SysRole::getUpdatedTime, LocalDateTime.now()).
                    eq(SysRole::getId, inVO.getId()));
        }
    }

    /**
     * 批量删除角色
     * @param inVO {@link RoleDeleteInVO}
     */
    @Override
    public void deletes(RoleDeleteInVO inVO) {
        sysRoleMapper.deleteBatchIds(inVO.getIds());
        sysMenuAuthRoleMapper.delete(Wrappers.<SysMenuAuthRole>lambdaQuery().
                in(SysMenuAuthRole::getRoleId, inVO.getIds()));
    }

    /**
     * 获取角色树
     * @return {@link List<RoleTreeOutVO>}
     */
    @Override
    public List<RoleTreeOutVO> getTree() {
        List<SysRole> sysRoleList = sysRoleMapper.selectList(Wrappers.lambdaQuery());
        List<RoleTreeOutVO> outVOList = Lists.newArrayList();
        if (CollUtil.isNotEmpty(sysRoleList)) {
            outVOList.addAll(sysRoleList.stream().map(sysRole -> {
                RoleTreeOutVO outVO = new RoleTreeOutVO();
                outVO.setId(sysRole.getId());
                outVO.setLabel(sysRole.getRoleName());
                return outVO;
            }).collect(Collectors.toList()));
        }
        return outVOList;
    }
}
